package org.ovirt.mobile.movirt.rest.client.httpconverter; /** * Created by suomiy on 10/17/16. */ import org.ovirt.mobile.movirt.model.enums.ConsoleProtocol; import org.ovirt.mobile.movirt.rest.ParseUtils; import org.ovirt.mobile.movirt.rest.dto.ConsoleConnectionDetails; import org.ovirt.mobile.movirt.util.ObjectUtils; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.AbstractHttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; public class VvFileHttpMessageConverter extends AbstractHttpMessageConverter<Object> { private static final String TAG = VvFileHttpMessageConverter.class.getSimpleName(); public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public static final String X_VIRT_VIEWER_MEDIA_TYPE = "application/x-virt-viewer"; public static final String VIRT_VIEWER_DEFINITION = "virt-viewer"; public VvFileHttpMessageConverter() { super(new MediaType("application", "x-virt-viewer", DEFAULT_CHARSET)); } @Override protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { Object result = null; InputStream inputStream = inputMessage.getBody(); try { result = convertStreamToConsoleConnectionDetails(inputStream); } catch (Exception x) { throw new IllegalStateException("Couldn't parse .vv file response", x); } finally { ObjectUtils.closeSilently(inputStream); } return result; } @Override public boolean canRead(Class<?> clazz, MediaType mediaType) { return super.canRead(clazz, mediaType); } @Override protected boolean canRead(MediaType mediaType) { return super.canRead(mediaType); } @Override public boolean canWrite(Class<?> clazz, MediaType mediaType) { return false; } @Override protected boolean canWrite(MediaType mediaType) { return false; } @Override protected boolean supports(Class<?> clazz) { return clazz == ConsoleConnectionDetails.class; } @Override protected void writeInternal(Object t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { throw new UnsupportedOperationException(); } private ConsoleConnectionDetails convertStreamToConsoleConnectionDetails(InputStream is) throws IOException { Map<String, String> vvFileMap = new HashMap<>(); Scanner sc = new Scanner(is, DEFAULT_CHARSET.name()); Pattern pattern = Pattern.compile("^([^#\\[][^=]*)=(.*)$"); Pattern definitionPattern = Pattern.compile("^\\[([^\\]]*)\\]$"); boolean virtViewerBlockFound = false; while (sc.hasNextLine()) { String line = sc.nextLine(); Matcher definitionMatcher = definitionPattern.matcher(line); if (definitionMatcher.matches()) { String definition = definitionMatcher.group(1); virtViewerBlockFound = definition.equals(VIRT_VIEWER_DEFINITION); continue; } if (!virtViewerBlockFound) { continue; } Matcher matcher = pattern.matcher(line); if (matcher.matches()) { MatchResult result = matcher.toMatchResult(); vvFileMap.put(result.group(1), result.group(2)); } } ConsoleProtocol protocol = ConsoleProtocol.mapProtocol(vvFileMap.get(VvFileParam.TYPE)); String address = vvFileMap.get(VvFileParam.HOST); String password = vvFileMap.get(VvFileParam.PASSWORD); String subject = vvFileMap.get(VvFileParam.HOST_SUBJECT); String unescapedCa = vvFileMap.get(VvFileParam.CA); String certificate = unescapedCa == null ? "" : unescapedCa.replace("\\n", "\n"); int port = ParseUtils.intOrDefault(vvFileMap.get(VvFileParam.PORT)); int tlsPort = ParseUtils.intOrDefault(vvFileMap.get(VvFileParam.TLS_PORT)); return new ConsoleConnectionDetails(protocol, address, port, tlsPort, password, subject, certificate); } interface VvFileParam { String TYPE = "type"; String HOST = "host"; String PORT = "port"; String TLS_PORT = "tls-port"; String PASSWORD = "password"; String HOST_SUBJECT = "host-subject"; String CA = "ca"; } }